<?php
// +----------------------------------------------------------------------
// | 双擎基础框架 [ 基于ThinkLibrary扩展 ]
// +----------------------------------------------------------------------
// | 感谢ThinkLibrary原作者Anyon的封装
// +----------------------------------------------------------------------
// | Copyright (c) 2022~2024 https://www.sqm.la All rights reserved.
// +----------------------------------------------------------------------
// | Author: rotoos <87291030@qq.com>
// +----------------------------------------------------------------------
namespace think\admin\model;

use think\admin\Model;

/**
 * 模型基础类
 * @class Base
 * @package think\admin\model
 */
class Base extends Model
{
    /**
     * @var string
     */
    protected $pk = 'id';
    /**
     * @var bool
     */
    protected $autoWriteTimestamp = true;

    /**
     * 设置主键类型
     * @var string
     */
    protected string $keyType = 'int';

    /**
     * 关闭自增
     * @var bool
     */
    protected bool $autoIncrement = false;

    /**
     * 自增序列号
     * @var int
     */
    protected static int $sequence = 0;

    /**
     * 序列号最大值
     * @var int
     */
    protected static int $maxSequence = 999;

    /**
     * 字段转驼峰
     * @var bool
     */
    protected $convertNameToCamel = true;

    /**
     * 开启自定义主键生成
     * @return void
     * @throws \Exception
     */
    // 定义模型的事件
    protected static function onBeforeInsert($model)
    {
        $model->id = self::generateUniqueTimestampId();
    }

    /**
     * 生成时间戳加自增ID
     * @return int
     * @throws \Exception
     */
    protected static function generateUniqueTimestampId(): int
    {
        // 使用数据库锁确保并发时ID的唯一性
        return static::mk()->transaction(function () {
            do {
                $timestamp = floor(microtime(true) * 1000);
                self::$sequence = (self::$sequence + 1) % (self::$maxSequence + 1);
                if (self::$sequence === 0) {
                    self::$sequence = 1;
                }
                $id = $timestamp . sprintf('%03d', self::$sequence);
            } while (static::mk()->where('id', $id)->findOrEmpty()->isExists());

            return (int) $id;
        });
    }

    /**
     * 格式化输出手机号
     * @param $value
     * @return array|string|string[]
     */
    public function getPhoneAttr($value): array|string
    {
        return substr_replace($value, '****', 3, 4);
    }

    /**
     * 格式化输出邮箱
     * @param $value
     * @return string
     */
    public function getEmailAttr($value): string
    {
        $emailArray = explode('@', $value);
        $emailArray[0] = substr($emailArray[0], 0, 1) . str_repeat('*', strlen($emailArray[0]) - 2) . substr($emailArray[0], -1);
        return implode('@', $emailArray);
    }

    /**
     * 格式化输出时间
     * @param mixed $value
     * @return string
     */
    public function getCreateTimeAttr($value): string
    {
        return format_datetime($value);
    }

    /**
     * 格式化输出时间
     * @param mixed $value
     * @return string
     */
    public function getUpdateTimeAttr($value): string
    {
        return format_datetime($value);
    }

    /**
     * 时间写入格式化
     * @param mixed $value
     * @return string
     */
    public function setCreateTimeAttr($value): string
    {
        return is_string($value) ? str_replace(['年', '月', '日'], ['-', '-', ''], $value) : $value;
    }

    /**
     * 时间写入格式化
     * @param mixed $value
     * @return string
     */
    public function setUpdateTimeAttr($value): string
    {
        return $this->setCreateTimeAttr($value);
    }

}